package com.boat.ai.util;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAccumulator;

public class SnowflakeGenerator {
    private static final long EPOCH = 1661932800000L; // 2025-01-01
    private final long workerId;
    private final long datacenterId;
    private final AtomicLong sequence = new AtomicLong(0);
    private volatile long lastTimestamp = -1L;
    private final LongAccumulator timeAccumulator;

    public SnowflakeGenerator(long workerId, long datacenterId) {
        this.workerId = workerId & 0x1F; // 5bit
        this.datacenterId = datacenterId & 0x1F;
        this.timeAccumulator = new LongAccumulator((prev, now) ->
                now > prev ? now : prev + 1, System.currentTimeMillis());
    }

    public long nextId() {
        long timestamp = timeAccumulator.get();
        long seq = sequence.getAndUpdate(s -> (s + 1) & 0xFFF);

        if (timestamp == lastTimestamp && seq == 0) {
            timestamp = waitNextMillis(timestamp);
        }
        lastTimestamp = timestamp;

        return ((timestamp - EPOCH) << 22)
                | (datacenterId << 17)
                | (workerId << 12)
                | seq;
    }

    private long waitNextMillis(long last) {
        long now;
        do {
            now = System.currentTimeMillis();
        } while (now <= last);
        return now;
    }
}
